using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

[assembly: WebResource("CodeStory.WebControls.Resource.EditableLabel.js", "application/x-javascript")]

namespace CodeStory.WebControls
{
	[ParseChildren(false)]
	[DefaultProperty("Text")]
	[ToolboxData("<{0}:EditableLabel runat=server></{0}:EditableLabel>")]
	public class EditableLabel : WebControl,ITextControl,IPostBackDataHandler
	{
		[DefaultValue("Save")]
		public string SaveText {
			get {
				object obj = ViewState["SaveText"];
				return obj == null ? "Save" : (string)obj;
			}
			set { ViewState["SaveText"] = value; }
		}

		[DefaultValue("Cancel")]
		public string CancelText {
			get { 
				object obj = ViewState["CancelText"];
				return obj == null ? "Cancel" : (string)obj;
			}
			set { ViewState["CancelText"] = value; }
		}

		[Browsable(true)]
		[DefaultValue("")]
		public string EditClassName {
			get {
				object obj = ViewState["EditClassName"];
				return obj == null ? string.Empty : (string)obj;
			}
			set { ViewState["EditClassName"] = value; }
		}
		[Browsable(true)]
		[DefaultValue("")]
		public string EditStyleString {
			get {
				object obj = ViewState["EditStyleString"];
				return obj == null ? "border : solid 1px red;" : (string)obj;
			}
			set { ViewState["EditStyleString"] = value; }
		}

		#region ITextControl Members

		public string Text {
			get {
				object obj = ViewState["Text"];
				return obj == null ? string.Empty : (string)obj;
			}
			set {
				ViewState["Text"] = value;
			}
		}

		string ITextControl.Text {
			get {
				return this.Text;
			}
			set {
				this.Text = value;
			}
		}

		#endregion

		StringBuilder _script;
		private StringBuilder InternalScript {
			get {
				if (_script == null) {
					_script = new StringBuilder(512);
				}
				return _script;
			}
		}
		protected override void AddParsedSubObject(object obj) {
			if (this.HasControls()) {
				base.AddParsedSubObject(obj);
			} else if (obj is LiteralControl) {
				this.Text = ((LiteralControl)obj).Text;
			}
		}

		protected override void CreateChildControls() {
			//base.CreateChildControls();
			ChildControlsCreated = true;
			Label lbl = new Label();
			Controls.Add(lbl);
			lbl.Text = Text;
			lbl.ControlStyle.CopyFrom(this.ControlStyle);
			lbl.Attributes.Add("ondblclick", "javascript:return EditableLabel.StartEdit(" + this.ClientID + "Object);");
			//lbl.Attributes.Add("onblur","javascript:EditableLabel.Blur(" + this.ClientID + "Object);");
			

			Panel c = new Panel();
			Controls.Add(c);
			c.Style.Add(HtmlTextWriterStyle.Display, "none");
			c.Style.Add(HtmlTextWriterStyle.Position, "absolute");
			Button save = new Button();
			c.Controls.Add(save);
			save.Text = SaveText;
			save.Attributes.Add("onclick", "javascript:return EditableLabel.SaveEdit(" + this.ClientID + "Object);");
			Button cancel = new Button();
			c.Controls.Add(cancel);
			cancel.Text = CancelText;
			cancel.Attributes.Add("onclick","javascript:return EditableLabel.CancelEdit("+this.ClientID+"Object);");

			string stylestring = string.Empty;
			if (ControlStyleCreated) {
				StringBuilder sb = new StringBuilder();
				System.IO.StringWriter w = new System.IO.StringWriter(sb);
				HtmlTextWriter writer = new HtmlTextWriter(w);
				ControlStyle.AddAttributesToRender(writer, lbl);
				writer.Flush();
				stylestring = sb.ToString();
			}

			InternalScript.Append("var ").Append(this.ClientID).Append("Object = {")
			.Append("\n\r\tLabel : '").Append(lbl.ClientID)
			.Append("',\n\r\tPanel: '").Append(c.ClientID)
			.Append("',\n\r\tHidden : '").Append(this.ClientID)
			.Append("',\n\r\tSave : '").Append(save.ClientID)
			.Append("',\n\r\tCancel : '").Append(cancel.ClientID)
			.Append("',\n\r\tEditClassName : '").Append(EditClassName)
			.Append("',\n\r\tEditStyleString : '").Append(EditStyleString)
			.Append("',\n\r\tClassName : '").Append(CssClass)
			.Append("',\n\r\tStyleString : '").Append(stylestring)
			.Append("',\n\r\tText : '").Append(Text)
			.Append("'\n\r};");
		}

		protected override void OnPreRender(EventArgs e) {
			if (Page != null) {
				Page.ClientScript.RegisterHiddenField(this.ClientID, Text);
				Page.ClientScript.RegisterClientScriptResource(typeof(DataSourceHelper), "CodeStory.WebControls.Resource.CodeStory.js");
				Page.ClientScript.RegisterClientScriptResource(GetType(), "CodeStory.WebControls.Resource.EditableLabel.js");
				Page.ClientScript.RegisterClientScriptBlock(GetType(), "EditableLabel", InternalScript.ToString(), true);
			} 
Page.RegisterRequiresPostBack(this);
			base.OnPreRender(e);
		}

		#region IPostBackDataHandler Members

		public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection) {
			//throw new Exception("The method or operation is not implemented.");
			string text = postCollection[this.ClientID];
			if (!string.Equals(text, Text)) {
				Text = text;
				return true;
			}
			return false;
		}

		public void RaisePostDataChangedEvent() {
			OnTextChanged();
		}

		#endregion

		private static readonly object TextChangedEventObject = new object();
		public event EventHandler TextChanged {
			add { Events.AddHandler(TextChangedEventObject,value); }
			remove { Events.RemoveHandler(TextChangedEventObject, value); }
		}

		protected virtual void OnTextChanged() {
			EventHandler handler = (EventHandler)Events[TextChangedEventObject];
			if (handler != null) {
				handler(this, EventArgs.Empty);
			}
		}
	}
}
